namespace ObjectPersistence {
    using System;
    using System.Text;
    using System.Collections;
    using System.Data.Common;
    using System.Transactions;
    using System.Collections.Generic;
    
    public partial class RoleAssembler : AssemblerBaseUpdatable<KYO.DAL.Role, RoleCriteria, RoleRowMap, RoleDomainObjectFactory> {
        public RoleAssembler() {
            base.connection = new System.Data.SqlClient.SqlConnection(GlobalUtil.Constants.ConnectionString);
        }
        protected override System.Data.Common.DbConnection InstanceConnection {
            get {
                return this.connection;
            }
        }
        /// <summary>Reads a single object from the database corresponding to the object keys which are passed in</summary>
        public KYO.DAL.Role ReadSingleByKey(int RoleId) {
            RoleCriteria criteria = new RoleCriteria();
            criteria.Set_RoleId(RoleCriteria.AVAILABLE_OPERATORS.EQUALS, RoleId);
            return this.ReadSingle(criteria);
        }

        internal override void MakePersistent(KYO.DAL.Role PersistentObject, bool cascade, System.Data.Common.DbCommand comm) {
            if ((PersistentObject.IsNew == false)) {
                if ((GlobalUtil.Constants.ObjectMapKYOPHUONGDOPC.Contains(PersistentObject.ROKeyString) 
                            && (PersistentObject.ChangesMade == false))) {
                    return;
                }
                if ((GlobalUtil.Constants.ObjectMapKYOPHUONGDOPC.Contains(PersistentObject.ROKeyString) == false)) {
                    GlobalUtil.Constants.ObjectMapKYOPHUONGDOPC.Add(PersistentObject.ROKeyString);
                }
            }

            if ((PersistentObject.IsNew || PersistentObject.ChangesMade)) {
                RoleUpdateFactory updateFactory = new RoleUpdateFactory();
                comm.Parameters.Clear();
                if ((PersistentObject.IsNew == false)) {
                    updateFactory.updateCommandText(PersistentObject, comm);
                    int numRows = comm.ExecuteNonQuery();
                    if ((numRows == 0)) {
                        throw new NoRowsUpdated();
                    }
                }
                else {
                    updateFactory.insertCommandText(PersistentObject, comm);
                    comm.ExecuteNonQuery();
                    GlobalUtil.Constants.ObjectMapKYOPHUONGDOPC.Add(PersistentObject.ROKeyString);
                    PersistentObject.IsNew = false;
                }
            }
            PersistentObject.ChangesMade = false;
            if (cascade) {
                UserAssembler tempUserAssembler = new UserAssembler();

                if ((PersistentObject.IsUserCollNull() == false)) {
                    for (int i1 = 0; (i1 < PersistentObject.UserColl.Count); i1 = (i1 + 1)) {
                        comm.Parameters.Clear();
                        tempUserAssembler.MakePersistent(PersistentObject.UserColl[i1], cascade, comm);
                    }
                    PersistentObject.UserColl.Clean();
                    this.InsertAddedUserCollMappingTable(PersistentObject, comm);
                    this.RemoveDeletedUserCollMappingTableEntries(PersistentObject, comm);
                    PersistentObject.UserColl.Synch();
                }
                tempUserAssembler.Dispose();
            }
        }

        internal override void Delete(KYO.DAL.Role PersistentObject, System.Data.Common.DbCommand comm) {
            this.DeleteUserCollMappingTable(PersistentObject, comm);

            comm.Parameters.Clear();

            RoleSelectionFactory tempRoleSelectionFactory = new RoleSelectionFactory();
            string sql = "DELETE FROM [dbo].[Role]";
            comm.CommandText = sql;
            tempRoleSelectionFactory.getDefaultSelection(PersistentObject, comm);
            comm.ExecuteNonQuery();
        }

        #region Manage Mapping Tables
        private void InsertAddedUserCollMappingTable(KYO.DAL.Role PersistentObject, System.Data.Common.DbCommand comm) {
            comm.CommandText = "IF NOT EXISTS (SELECT 1 FROM [dbo].[UserInRole] (nolock) WHERE [RoleId] = @larg0 " +
                "AND [UserId] = @rarg1) INSERT INTO [dbo].[UserInRole] ([RoleId] , [UserId] ) VAL" +
                "UES (@larg0, @rarg1)";
            for (int i = 0; (i < PersistentObject.UserColl.Added.Count); i = (i + 1)) {
                comm.Parameters.Clear();
                ObjectPersistenceHelper.AddParameterWithValue(comm, "@larg0", PersistentObject.RoleId);
                ObjectPersistenceHelper.AddParameterWithValue(comm, "@rarg1", PersistentObject.UserColl.Added[i].UserID);
                comm.ExecuteNonQuery();
            }
        }

        private void DeleteUserCollMappingTable(KYO.DAL.Role PersistentObject, System.Data.Common.DbCommand comm) {
            comm.Parameters.Clear();
            comm.CommandText = "DELETE FROM [dbo].[UserInRole] WHERE [RoleId]=@arg0";
            ObjectPersistenceHelper.AddParameterWithValue(comm, "@arg0", PersistentObject.RoleId);
            comm.ExecuteNonQuery();
        }

        private void RemoveDeletedUserCollMappingTableEntries(KYO.DAL.Role PersistentObject, System.Data.Common.DbCommand comm) {
            comm.CommandText = "DELETE FROM [dbo].[UserInRole] WHERE  [RoleId]=@arg0 AND  [UserId]=@rarg1";
            for (int i = 0; (i < PersistentObject.UserColl.Deleted.Count); i = (i + 1)) {
                comm.Parameters.Clear();
                ObjectPersistenceHelper.AddParameterWithValue(comm, "@arg0", PersistentObject.RoleId);
                ObjectPersistenceHelper.AddParameterWithValue(comm, "@rarg1", PersistentObject.UserColl.Deleted[i].UserID);
                comm.ExecuteNonQuery();
            }
        }
        #endregion

        #region Manage Child Objects / Collections
        /// Reads the KYO.DAL.User from the database corresponding to the object keys passed as parameters
        // <param name="localRoleId">Corresponds to Role attribute RoleId</param
        // <param name="local">Corresponds to Role attribute </param
        public BusinessLayerHelper.PersistentList<KYO.DAL.User> GetUserColl(int localRoleId) {
            BusinessLayerHelper.PersistentList<KYO.DAL.User> result = new BusinessLayerHelper.PersistentList<KYO.DAL.User>();
            System.Data.Common.DbConnection tempConnection = this.InstanceConnection;
            try {
                tempConnection.Open();
                System.Data.Common.DbCommand comm = tempConnection.CreateCommand();
                comm.CommandText = (UserAssembler.SELECT + " FROM [dbo].[UserInRole] INNER JOIN [dbo].[User] ON [dbo].[UserInRole].[UserId] =" +
                    " [dbo].[User].[UserID] WHERE [dbo].[UserInRole].[RoleId] = @arg1");
                ObjectPersistenceHelper.AddParameterWithValue(comm, "@arg1", localRoleId);
                UserAssembler _tempAssem = new UserAssembler();
                result.FillData(_tempAssem.ReadCollectionCustom(comm));
            }
            finally {
                tempConnection.Close();
            }
            return result;
        }
        #endregion

        #region Helper Utilities
        protected override RoleRowMap fillRowMap(System.Data.Common.DbDataReader reader) {
            RoleRowMap result = new RoleRowMap();
            result.RoleId = reader.GetInt32(reader.GetOrdinal("dboRoleDOTRoleId"));
            result.Name = reader.GetString(reader.GetOrdinal("dboRoleDOTName"));
            return result;
        }
        internal override void ClearList() {
            GlobalUtil.Constants.ObjectMapKYOPHUONGDOPC.Clear();
        }

        public override string Abstract_SELECT {
            get {
                return ("SELECT " + RoleAssembler.RawFields);
            }
        }
        protected override string InstanceTable {
            get {
                return "[dbo].[Role]";
            }
        }
        public const string RawFields = "[dbo].[Role].[RoleId] AS dboRoleDOTRoleId, [dbo].[Role].[Name] AS dboRoleDOTName";
        public const string SELECT = "SELECT [dbo].[Role].[RoleId] AS dboRoleDOTRoleId, [dbo].[Role].[Name] AS dboRoleD" +
            "OTName";
        #endregion
    }
}
